﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cofoundry.Domain
{
    /// <summary>
    /// A small page object focused on providing routing data. A PageRoute returned from one of the
    /// standard Cofoundry queries is typically stored in a cache to make sure access is fast.
    /// </summary>
    public class PageRoute : IPageRoute, IPublishableEntity
    {
        /// <summary>
        /// Database identifier for the page.
        /// </summary>
        public int PageId { get; set; }
        
        /// <summary>
        /// Optional locale of the page.
        /// </summary>
        public ActiveLocale Locale { get; set; }

        /// <summary>
        /// The directory this page is in.
        /// </summary>
        public PageDirectoryRoute PageDirectory { get; set; }

        /// <summary>
        /// The path of the page within the directory. This will be
        /// unique within the directory the page is parented to.
        /// </summary>
        public string UrlPath { get; set; }

        /// <summary>
        /// The full path of the page including directories and the locale. 
        /// </summary>
        public string FullPath { get; set; }

        /// <summary>
        /// The title of the page for the currently published version, falling
        /// back to the draft version is there is no published version.
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Indicates if the page is marked as published or not, which allows the page
        /// to be shown on the live site if the PublishDate has passed.
        /// </summary>
        public PublishStatus PublishStatus { get; set; }

        /// <summary>
        /// The date after which the page can be shown on the live site.
        /// </summary>
        public DateTime? PublishDate { get; set; }

        /// <summary>
        /// Indicates whether there is a draft version of this page available.
        /// </summary>
        public bool HasDraftVersion { get; set; }

        /// <summary>
        /// Indicates whether there is a published version of this page available.
        /// </summary>
        public bool HasPublishedVersion { get; set; }

        /// <summary>
        /// Routing information particular to specific versions.
        /// </summary>
        public ICollection<PageVersionRoute> Versions { get; set; }

        /// <summary>
        /// Most pages are generic pages but they could have some sort of
        /// special function e.g. NotFound, CustomEntityDetails.
        /// </summary>
        public PageType PageType { get; set; }

        /// <summary>
        /// Indicates whether the page should show in the autogenerated site map
        /// that gets presented to search engine robots. Based on the draft version
        /// if no published version exists, so be careful to check the page is 
        /// published before making use of this.
        /// </summary>
        public bool ShowInSiteMap { get; set; }

        /// <summary>
        /// If this is of PageType.CustomEntityDetails, this is used
        /// to look up the routing.
        /// </summary>
        public string CustomEntityDefinitionCode { get; set; }

        #region public methods

        /// <summary>
        /// Determins if the page is within the specified directory path. Does
        /// not return true if it is in a subdirectory of the specified directory path.
        /// </summary>
        public bool IsInDirectory(string directoryPath)
        {
            if (PageDirectory == null) return false;

            if (Locale == null)
            {
                return PageDirectory.MatchesPath(directoryPath);
            }

            return PageDirectory.MatchesPath(directoryPath, Locale.LocaleId);
        }
        
        /// <summary>
        /// Indicates if this is the default file in the directory
        /// </summary>
        public bool IsDirectoryDefaultPage(int? localeId = null)
        {
            return string.IsNullOrWhiteSpace(UrlPath);
        }

        #endregion
    }
}
